#include <gtest/gtest.h>
#include "upgrade.h"
#include "base_log.h"
#include "base_init.h"
#include "common_init.h"
#include <fstream>
#include <filesystem>
#include <nlohmann/json.hpp>

namespace El {
namespace Upgrade {

namespace fs = std::filesystem;

class UpgradeTest : public ::testing::Test {
protected:
    static void SetUpTestSuite() {
        // 初始化基础库
        nlohmann::json config;
        config["log_file"] = "upgrade_test.log";
        El::Base::base_init(config);

        // 初始化配置
        config.clear();
        config["general"] = "upgrade_config";
        config["default"] = "default_config";
        El::Common::common_init(config);

        // 启动升级服务
        Upgrade::GetInstance().Start();
    }

    static void TearDownTestSuite() {
        Upgrade::GetInstance().Stop();
    }

    void SetUp() override {
        // 创建测试目录结构
        CreateTestPackage();
    }

    void TearDown() override {
        // 清理测试文件
        CleanupTestPackage();
    }

private:
    void CreateTestPackage() {
        // 创建测试包目录结构
        fs::create_directories("test_package/images");
        fs::create_directories("test_package/scripts");

        // 创建测试镜像文件
        CreateDummyFile("test_package/images/uboot.img", 1024);
        CreateDummyFile("test_package/images/kernel.img", 2048);
        CreateDummyFile("test_package/images/rootfs.img", 4096);

        // 创建测试脚本
        CreateTestScript("test_package/scripts/preinstall");
        CreateTestScript("test_package/scripts/postinstall");

        // 创建manifest文件
        CreateManifest();
    }

    void CreateDummyFile(const std::string& path, size_t size) {
        std::ofstream file(path, std::ios::binary);
        std::vector<char> data(size, 'A');
        file.write(data.data(), size);
    }

    void CreateTestScript(const std::string& path) {
        std::ofstream script(path);
        script << "#!/bin/bash\n";
        script << "echo 'Test script executed'\n";
        script << "exit 0\n";
    }

    void CreateManifest() {
        nlohmann::json manifest;
        manifest["product"]["name"] = "ipc100";
        manifest["product"]["hardware"] = "1.0.0";
        manifest["version"]["from"] = "V1.0.0";
        manifest["version"]["to"] = "V2.0.0";
        manifest["type"] = "full";
        manifest["compatibility"]["min_version"] = "V1.0.0";
        manifest["compatibility"]["max_version"] = "V3.0.0";
        
        manifest["files"] = nlohmann::json::array();
        manifest["files"].push_back({
            {"name", "uboot.img"},
            {"hash", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}  // 空文件的SHA256
        });

        std::ofstream file("test_package/manifest.json");
        file << manifest.dump(4);
    }

    void CleanupTestPackage() {
        fs::remove_all("test_package");
    }
};

TEST_F(UpgradeTest, StartStopTest) {
    EXPECT_EQ(Upgrade::GetInstance().GetStatus(), UpgradeStatus::IDLE);
    
    Upgrade::GetInstance().Stop();
    EXPECT_EQ(Upgrade::GetInstance().GetStatus(), UpgradeStatus::IDLE);
    
    Upgrade::GetInstance().Start();
    EXPECT_EQ(Upgrade::GetInstance().GetStatus(), UpgradeStatus::IDLE);
}

TEST_F(UpgradeTest, VerifyPackageTest) {
    EXPECT_TRUE(Upgrade::GetInstance().VerifyPackage("test_package"));
    EXPECT_EQ(Upgrade::GetInstance().GetStatus(), UpgradeStatus::VERIFYING);
    EXPECT_TRUE(Upgrade::GetInstance().GetLastError().empty());
}

TEST_F(UpgradeTest, VerifyInvalidPackageTest) {
    EXPECT_FALSE(Upgrade::GetInstance().VerifyPackage("invalid_package"));
    EXPECT_FALSE(Upgrade::GetInstance().GetLastError().empty());
}

TEST_F(UpgradeTest, UpgradeProcessTest) {
    EXPECT_TRUE(Upgrade::GetInstance().VerifyPackage("test_package"));
    EXPECT_TRUE(Upgrade::GetInstance().StartUpgrade("test_package"));
    
    EXPECT_EQ(Upgrade::GetInstance().GetStatus(), UpgradeStatus::SUCCESS);
    EXPECT_FLOAT_EQ(Upgrade::GetInstance().GetUpgradeProgress(), 100.0f);
}

TEST_F(UpgradeTest, StopUpgradeTest) {
    EXPECT_TRUE(Upgrade::GetInstance().VerifyPackage("test_package"));
    EXPECT_TRUE(Upgrade::GetInstance().StartUpgrade("test_package"));
    
    EXPECT_TRUE(Upgrade::GetInstance().StopUpgrade());
    EXPECT_EQ(Upgrade::GetInstance().GetStatus(), UpgradeStatus::IDLE);
}

TEST_F(UpgradeTest, VersionCheckTest) {
    std::string version = Upgrade::GetInstance().GetCurrentVersion();
    EXPECT_FALSE(version.empty());
    EXPECT_EQ(version, "V1.0.0");  // 当前硬编码的版本号
}

} // namespace Upgrade
} // namespace El